#![allow(unused)]

use std::any::Any;
use std::collections::HashMap;
use std::sync::Arc;

use thiserror::Error;

use crate::asset;

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum ResourceTy {
    Balance(asset::Asset),
}

//struct Resource {
//    data: Arc<dyn Any>,
//    ty: ResourceTy,
//}

/// Resource identifier for tracking resources in an inventory.
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct ResId(u64);

use crate::network;

#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub struct ResLockId(u64);

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum LockType {
    Shared,
    Exclusive,
}

#[derive(Debug, Error)]
pub enum Error {
    #[error("unknown resource {0:?}")]
    InvalidResourceId(ResId),

    #[error("can't lock resource {0:?}, already locked as {1:?}")]
    ResourceLocked(ResLockId, LockType),
}

pub struct Inventory {
    // TODO
}

pub struct Resource {
    props: HashMap<PropTy, Prop>,
}

impl Resource {
    pub fn get_prop_by_ty(&self, ty: PropTy) -> Option<Prop> {
        self.props.get(&ty)
    }
}

#[derive(Clone, Eq, PartialEq)]
pub enum Prop {
    Chain(network::Chain),
    Amount(asset::Amount),
    Asset(asset::Asset),
}

impl Prop {
    pub fn ty(&self) -> PropTy {
        use Prop::*;
        match self {
            Chain(_) => PropTy::Chain,
            Amount(_) => PropTy::Amount,
            Asset(_) => PropTy::Asset,
        }
    }
}

#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
pub enum PropTy {
    Chain,
    Amount,
    Asset,
}
